#pragma once

#include "thread/thread_pool.h"
#include "thread/lock.h"

#include "win32_thread.h"

#include <queue>
#include <functional>
#include <vector>

namespace renderit
{
	namespace thread
	{
		class win32_thread_pool : public thread_pool
		{
		public:
			win32_thread_pool(const std::string& name, uint32 count);
			virtual ~win32_thread_pool() {}

		public:
			virtual void dispatch(std::function<void()>&& func) override;

		public:
			std::function<void()> fetch_work();
			const std::string& name() { return name_; }
			
		private:
			std::string name_;

			std::vector<HANDLE> threads_;

			// queued workers
			semaphore work_sem_;
			std::queue<std::function<void()>> work_queue_;
			spinlock work_queue_lock_;
		};

		class win32_main_thread : public main_thread
		{
		public:
			win32_main_thread();
			virtual ~win32_main_thread() {}

		public:
			virtual void dispatch(std::function<void()>&& func) override;

		public:
			virtual void do_work() override;

		private:
			// queue workers
			std::queue<std::function<void()>> work_queue_;
			spinlock work_queue_lock_;
		};
	}
}